﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Text.RegularExpressions;

namespace OpenWaves
{
    public static class StringExtensions
    {
        public static string Truncate(this string value, int maxLength)
        {
            Contract.Requires<ArgumentOutOfRangeException>(maxLength >= 0);

            if (value == null)
                return String.Empty;

            if (value.Length <= maxLength)
                return value;

            return value.Substring(0, maxLength);
        }

        public static IEnumerable<int> FindAll(this string source, string value)
        {
            return FindAll(source, value, StringComparison.Ordinal);
        }

        public static IEnumerable<int> FindAll(this string source, string value, StringComparison comparisonType)
        {
            Contract.Requires<ArgumentNullException>(source != null);
            Contract.Requires<ArgumentNullException>(String.IsNullOrEmpty(value) == false);
            Contract.Ensures(Contract.Result<IEnumerable<int>>() != null);

            var last = 0;
            var result = new List<int>();
            while (true)
            {
                int index = source.IndexOf(value, last, comparisonType);
                if (index == -1)
                {
                    break;
                }
                result.Add(index);
                last = index + 1;
            }
            return result;
        }

        public static string Capitalize(this string value)
        {
            Contract.Requires<ArgumentNullException>(value != null);
            Contract.Ensures(Contract.Result<string>() != null);

            if (value.Length == 0)
                return value;

            if (value.Length == 1)
                return value.Substring(0, 1).ToUpper(CultureInfo.InvariantCulture);

            return value.Substring(0, 1).ToUpper(CultureInfo.InvariantCulture) + value.Substring(1);
        }

        public static string SplitCamelCase(this string input)
        {
            Contract.Requires(string.IsNullOrEmpty(input) == false);

            var result = Regex.Replace(input, @"\B([A-Z][a-z])", " $1");
            result = Regex.Replace(result, @"\B([^\d])(\d)", "$1 $2");
            return result.Trim();
        }

        public static bool IsNullOrWhiteSpace(this string input)
        {
            #if NET_40_OR_GREATER
                return string.IsNullOrWhiteSpace(input);
            #else
                return string.IsNullOrEmpty(input) || input.Trim().Length == 0;
            #endif
        }
    }
}
